package org.example.order.config;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;

/**
 * @author tds
 * @version 1.0.0
 * @Company
 * @ClassName CustomLoadbalancerConfiguration
 * @Description 自定义负载均衡策略
 *      不要使用@Configuration注解。否则会变成全局的一个负载均衡配置器了
 *      官网原文：“The classes you pass as @LoadBalancerClient or @LoadBalancerClients configuration arguments should
 *      either not be annotated with @Configuration or be outside component scan scope.”
 *      https://docs.spring.io/spring-cloud-commons/docs/current/reference/html/#spring-cloud-loadbalancer
 * @Date 2023-04-15 14:01
 */
public class RandomLoadbalancerConfiguration {

    /**
     * 随机负载均衡器
     *     默认RoundRobinLoadBalancer轮询负载均衡器，但如果开启了nacos负载均衡(spring.cloud.loadbalancer.nacos.enabled=true)，则使用
     * nacos的负载均衡配置（com.alibaba.cloud.nacos.loadbalancer.LoadBalancerNacosAutoConfiguration）
     *     阿里的负载均衡器（com.alibaba.cloud.nacos.loadbalancer.NacosLoadBalancer）是先根据配置
     * spring.cloud.nacos.discovery.clusterName获取元数据的nacos.cluster相同的实例（没配置不过滤），然后根据配置的权重随机获取一个实例。
     *     这里通过Primary注解表示优先使用随机负载均衡器
     *
     * @param environment
     * @param loadBalancerClientFactory
     * @return
     */
    @Bean
    @Primary
    public ReactiveLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClientFactory
                .getLazyProvider(name, ServiceInstanceListSupplier.class), name);
    }


}